原本想繼續介紹 ES6 的 Class 與 set & map,但是感覺還沒有足夠的了解,所以也許等明年鐵人賽的時候再來補坑QQ
因為 JS 在 ES6 才加入 Class 的概念,所以需要使用原型來繼承。
繼承:指的是一個物件取用另一個物件的方法及屬性。
每個物件、函式都有自己的原型,會以 __proto__
來顯示。
上面的 __proto__
就是原型。
當你想使用物件內的方法時,通常都會透過點運算子(" . "符號)來呼叫
let protoType = {};
protoType.toString();
而順序上是這樣的,會先從該物件找,找不到才去原型找。在原型中找到後回傳,所以才看起來像是 protoType 變數
的方法,但是 protoType
明明就只是個空物件。
因此透過 console
後會發現其實是原型的方法。
這裡介紹兩個方法,但第一個方法僅用於幫助理解,強烈建議永遠不要用第一個方法。
使用 proto
來設定:
// 首先建立兩個物件
let JC = {
name: "JCchan",
age: 14
};
let JK = {
name: "JKchan",
age: 16
};
// 接著直接使用 __proto__ 來賦予繼承者(JK)他的原型(JC)
JK.__proto__ = JC;
console.log
後會發現 JK 的原型變成了 JC
使用 Object.setPrototypeof()
來設定:
// 一樣需要兩個物件
let JC = {
name: "JCchan",
age: 14
};
let JK = {
name: "JKchan",
age: 16
};
// 參數1放繼承者,參數2放原型
Object.setPrototypeOf(JK, JC);
console.log
後會有一樣的結果。
自己的原型也有原型,而剛剛說到點運算子會從主要的物件開始找方法,所以先在自己身上找找,找不到就跑去原型找,自己的原型找不到,也許原型的原型會有,就又跑去找(感覺在繞口令...
最後形成下面這張圖
這就是原型鏈
以上面的範例
JK 的原型為 JC,JC 自己的原型就是 Object 的原型。
let str = '';
let obj = {};
let arr = [];
str.__proto__;
obj.__proto__;
arr.__proto__;
以 arr
為例,可以看到原型有熟悉的 filter
、map
等等。這是因為當被呼叫時,JavaScript 的引擎會製作相對應的原型給你。
在聲明一次,__proto__
因為會不斷找尋原型,所以會使得效能下降,因此在這裡只為了方便介紹使用。
以上粗略介紹希望可以很精簡的告訴大家原型是甚麼~~